<script setup lang="ts">
import mapboxgl from 'mapbox-gl'
import { URL_CONFIGS } from '@/constants'
import http from '@/utils/http'

// const baseUrl = import.meta.env.VITE_BASE_URL
const tableData = ref<{ pathGuide: string; icon: string }[]>([])
const loading = ref(false)
let startMarker: any = null
let startNameMarker: any = null
let endMarker: any = null
let endNameMarker: any = null

function clickAddStartPoint(e) {
  if (startMarker) {
    startMarker.remove()
    startMarker = null
  }
  if (startNameMarker) startNameMarker.remove()

  startMarker = new mapboxgl.Marker({ color: 'red' }).setLngLat(e.lngLat).addTo(map)
  const element = document.createElement('div')
  element.classList.add('start-point-name')
  element.innerText = '起始点'
  startNameMarker = new mapboxgl.Marker({
    element,
    anchor: 'left',
    offset: [5, 15]
  })
    .setLngLat([e.lngLat.lng, e.lngLat.lat])
    .addTo(map)
}

function clickAddEndPoint(e) {
  if (endMarker) {
    endMarker.remove()
    endMarker = null
  }
  if (endNameMarker) endNameMarker.remove()
  endMarker = new mapboxgl.Marker({ color: 'green' }).setLngLat(e.lngLat).addTo(map)
  const element = document.createElement('div')
  element.classList.add('end-point-name')
  element.innerText = '终点'
  endNameMarker = new mapboxgl.Marker({
    element,
    anchor: 'left',
    offset: [5, 15]
  })
    .setLngLat([e.lngLat.lng, e.lngLat.lat])
    .addTo(map)
}

function addStartPoint() {
  map.off('click', clickAddEndPoint)
  map.on('click', clickAddStartPoint)
}

function addEndPoint() {
  map.off('click', clickAddStartPoint)
  map.on('click', clickAddEndPoint)
}

async function pathPlanning() {
  if (startMarker === null || endMarker === null) return ElMessage.error('请先添加起始点和终点!')
  tableData.value = [{ pathGuide: `开始导航`, icon: `/svg/start.svg` }]
  loading.value = true
  map.off('click', clickAddEndPoint)
  map.off('click', clickAddStartPoint)

  try {
    const parameter = {
      resultSetting: {
        returnEdgeFeatures: true,
        returnEdgeGeometry: true,
        returnEdgeIDs: true,
        returnNodeFeatures: true,
        returnNodeGeometry: true,
        returnNodeIDs: true,
        returnPathGuides: true,
        returnRoutes: true
      },
      weightFieldName: 'SmLength',
      barrierEdgeIDs: null,
      barrierNodeIDs: null,
      barrierPoints: null,
      turnWeightField: null
    }

    const start = startMarker.getLngLat()
    const end = endMarker.getLngLat()
    const pathAnalysisUrl = `${URL_CONFIGS.ROUTE_PLANNING_URL}?nodes=[{"x":${start.lng},"y":${start.lat}},{"x":${end.lng},"y":${end.lat}}]&parameter=${JSON.stringify(parameter)}`
    const res = await http.get<any>(pathAnalysisUrl)

    if (map.getLayer('pathDatas')) map.removeLayer('pathDatas')
    if (map.getSource('pathDatas')) map.removeSource('pathDatas')

    const edgeFeatureMap = new Map(
      res.pathList[0].edgeFeatures.map((item) => {
        const edgeFeature = item.fieldNames.reduce((acc, fieldName, index) => {
          acc[fieldName] = item.fieldValues[index]
          return acc
        }, {})
        return [edgeFeature.SMID, edgeFeature]
      })
    )

    let previousId = null // 用于保存上一个 item 的 id
    const pathGuideItems = res.pathList[0].pathGuideItems
      .filter((item) => item.id >= 0)
      .map(({ id, name, length, description }) => {
        if (description === '继续前行' && previousId !== null) name = String(previousId)
        previousId = id
        return { id, name, length, description }
      })

    const pathGuideItemsWithEdgeFeatures = pathGuideItems.map((item) => ({
      ...item,
      edgeFeature: edgeFeatureMap.get(item.name) || null
    }))

    pathGuideItemsWithEdgeFeatures.forEach((pathGuideItem, index) => {
      // 继续前行
      if (pathGuideItem.description === '继续前行') {
        if (pathGuideItem.edgeFeature.RN) {
          if (pathGuideItem.edgeFeature.NAME) {
            const pathGuide: string = `向 ${pathGuideItem.edgeFeature.RN}(${pathGuideItem.edgeFeature.NAME}) 方向继续前行`
            tableData.value.push({ pathGuide, icon: `/svg/up.svg` })
          } else {
            const pathGuide: string = `向 ${pathGuideItem.edgeFeature.RN} 方向继续前行`
            tableData.value.push({ pathGuide, icon: `/svg/up.svg` })
          }
        } else {
          tableData.value.push({ pathGuide: `继续前行`, icon: `/svg/up.svg` })
        }
      }

      // 行驶
      if (pathGuideItem.description.startsWith('向')) {
        if (pathGuideItem.edgeFeature.RN) {
          if (pathGuideItem.edgeFeature.NAME) {
            const pathGuide: string = `沿 ${pathGuideItem.edgeFeature.RN}(${pathGuideItem.edgeFeature.NAME}) 方向${pathGuideItem.description.substring(0, 2)}行驶 ${Math.round(pathGuideItem.length)} 米`
            tableData.value.push({ pathGuide, icon: `/svg/up.svg` })
          } else {
            const pathGuide: string = `沿 ${pathGuideItem.edgeFeature.RN} 方向${pathGuideItem.description.substring(0, 2)}行驶 ${Math.round(pathGuideItem.length)} 米`
            tableData.value.push({ pathGuide, icon: `/svg/up.svg` })
          }
        } else {
          const pathGuide: string = `${pathGuideItem.description.substring(0, 2)}行驶 ${Math.round(pathGuideItem.length)} 米`
          tableData.value.push({ pathGuide, icon: `/svg/up.svg` })
        }
      }

      // 转向
      if (pathGuideItem.description.includes('转')) {
        const iconMap = {
          左转: `/svg/left.svg`,
          右转: `/svg/right.svg`
        }
        const iconPath = iconMap[pathGuideItem.description]
        let pathGuide: string = ''
        if (pathGuideItemsWithEdgeFeatures[index + 1].edgeFeature.RN) {
          if (pathGuideItemsWithEdgeFeatures[index + 1].edgeFeature.NAME) {
            pathGuide = `${pathGuideItem.description} 驶入 ${pathGuideItemsWithEdgeFeatures[index + 1].edgeFeature.RN}(${pathGuideItemsWithEdgeFeatures[index + 1].edgeFeature.NAME}) 方向`
          } else {
            pathGuide = `${pathGuideItem.description} 驶入 ${pathGuideItemsWithEdgeFeatures[index + 1].edgeFeature.RN}`
          }
        } else {
          pathGuide = `${pathGuideItem.description}`
        }
        if (iconPath) tableData.value.push({ pathGuide, icon: iconPath })
      }
    })
    tableData.value.push({ pathGuide: `到达终点`, icon: `/svg/end.svg` })
    map.addSource('pathDatas', {
      type: 'geojson',
      data: {
        type: 'FeatureCollection',
        features: [
          {
            type: 'Feature',
            geometry: {
              type: 'LineString',
              coordinates: res.pathList[0].route.line.points.map((point) => [point.x, point.y])
            }
          }
        ]
      }
    })
    map.addLayer({
      id: 'pathDatas',
      type: 'line',
      source: 'pathDatas',
      layout: {},
      paint: {
        'line-color': '#FF0000',
        'line-opacity': 1,
        'line-width': 5
      }
    })
  } catch (error) {
    throw new Error(error instanceof Error ? error.message : '路径规划失败')
  } finally {
    loading.value = false
  }
}

function clear() {
  tableData.value = []
  if (map.getLayer('pathDatas')) {
    map.removeLayer('pathDatas')
    map.removeSource('pathDatas')
  }
  if (startMarker) {
    startMarker.remove()
    startMarker = null
  }
  if (startNameMarker) startNameMarker.remove()
  if (endMarker) {
    endMarker.remove()
    endMarker = null
  }
  if (endNameMarker) endNameMarker.remove()
  map.off('click', clickAddEndPoint)
  map.off('click', clickAddStartPoint)
}
</script>

<template>
  <div class="path">
    <div class="title">路径规划</div>
    <div class="path-container">
      <div class="buttom-panel">
        <el-button color="#2B333E" size="small" @click="addStartPoint">添加起始点</el-button>
        <el-button color="#2B333E" size="small" @click="addEndPoint">添加终点</el-button>
        <el-button color="#2B333E" size="small" @click="pathPlanning">规划路径</el-button>
        <el-button color="#2B333E" size="small" @click="clear">清除</el-button>
      </div>
      <div class="path-table">
        <transition name="fade">
          <el-table v-if="tableData.length > 0" v-loading="loading" :show-header="false" size="small" stripe height="20vh" :data="tableData" style="width: 100%">
            <el-table-column label="图标" width="40">
              <template #default="scope">
                <div style="display: flex; align-items: center">
                  <img :src="tableData[scope.$index].icon" alt="测距" style="width: 20px; height: 20px" />
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="pathGuide" label="pathGuide" />
          </el-table>
        </transition>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.path {
  position: absolute;
  bottom: 61vh;
  width: 350px;
  right: 54px;
  z-index: 9;
  border-radius: 6px;
  background-color: #0a1831a0;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;

  .title {
    height: 30px;
    margin-bottom: 5px;
    padding: 3px;
    font-size: 18px;
    font-weight: bold;
    color: #fff;
  }

  .path-container {
    // height: 6vh;
    display: flex;
    flex-direction: column;
    color: #ccc;

    .buttom-panel {
      margin-top: 10px;
      margin-left: 20px;
    }

    .path-table {
      position: relative;
      width: 100%;
      height: 100%;
      margin-bottom: 5px;
      padding: 10px;

      :deep(.el-table),
      :deep(.el-table__expanded-cell) {
        background-color: transparent;
        color: #93dcfe;
      }

      :deep(.el-table th) {
        background-color: #031c488f;
        user-select: none;
      }
      :deep(.el-table thead) {
        height: 10px;
      }

      // 表格内背景颜色
      :deep(.el-table tr),
      :deep(.el-table td) {
        background-color: transparent;
        border: 0px;
        color: #ffffffaf;
        height: 5px;
        font-family:
          Source Han Sans CN Normal,
          Source Han Sans CN Normal-Normal;
        font-weight: Normal;
      }

      // 修改高亮当前行颜色
      :deep(.el-table tbody tr:hover) > td {
        background: #0f4d99 !important;
      }

      // 表格斑马自定义颜色
      :deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
        background: #1f4b5c8e;
      }
    }

    span {
      width: 100px;
      margin-right: 10px;
    }
  }
}
</style>
